<script lang="ts" setup>
import type { ButtonInstance, ScrollbarInstance } from 'element-plus';

import type { AppLink } from './data';

import { nextTick, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';
import { getUrlNumberValue } from '@vben/utils';

import {
  ElButton,
  ElForm,
  ElFormItem,
  ElScrollbar,
  ElTooltip,
} from 'element-plus';

import { ProductCategorySelect } from '#/views/mall/product/category/components/';

import { APP_LINK_GROUP_LIST, APP_LINK_TYPE_ENUM } from './data';

/** APP 链接选择弹框 */
defineOptions({ name: 'AppLinkSelectDialog' });

const emit = defineEmits<{
  appLinkChange: [appLink: AppLink];
  change: [link: string];
}>();

const activeGroup = ref(APP_LINK_GROUP_LIST[0]?.name); // 选中的分组，默认选中第一个
const activeAppLink = ref({} as AppLink); // 选中的 APP 链接

const linkScrollbar = ref<ScrollbarInstance>(); // 右侧滚动条
const groupTitleRefs = ref<HTMLInputElement[]>([]); // 分组标题引用列表
const groupScrollbar = ref<ScrollbarInstance>(); // 分组滚动条
const groupBtnRefs = ref<ButtonInstance[]>([]); // 分组引用列表

const detailSelectDialog = ref<{
  id?: number;
  type?: APP_LINK_TYPE_ENUM;
}>({
  id: undefined,
  type: undefined,
}); // 详情选择对话框

const [Modal, modalApi] = useVbenModal({
  onConfirm() {
    emit('change', activeAppLink.value.path);
    emit('appLinkChange', activeAppLink.value);
    modalApi.close();
  },
});

const [DetailSelectModal, detailSelectModalApi] = useVbenModal({
  onConfirm() {
    detailSelectModalApi.close();
  },
});

defineExpose({ open });

/** 打开弹窗 */
async function open(link: string) {
  activeAppLink.value.path = link;
  modalApi.open();
  // 滚动到当前的链接
  const group = APP_LINK_GROUP_LIST.find((group) =>
    group.links.some((linkItem) => {
      const sameLink = isSameLink(linkItem.path, link);
      if (sameLink) {
        activeAppLink.value = { ...linkItem, path: link };
      }
      return sameLink;
    }),
  );
  if (group) {
    // 使用 nextTick 的原因：可能 Dom 还没生成，导致滚动失败
    await nextTick();
    handleGroupSelected(group.name);
  }
}

/** 处理 APP 链接选中 */
function handleAppLinkSelected(appLink: AppLink) {
  if (!isSameLink(appLink.path, activeAppLink.value.path)) {
    activeAppLink.value = appLink;
  }
  switch (appLink.type) {
    case APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST: {
      detailSelectDialog.value.type = appLink.type;
      // 返显
      detailSelectDialog.value.id =
        getUrlNumberValue(
          'id',
          `http://127.0.0.1${activeAppLink.value.path}`,
        ) || undefined;
      detailSelectModalApi.open();
      break;
    }
    default: {
      break;
    }
  }
}

/**
 * 处理右侧链接列表滚动
 *
 * @param {object} param0 滚动事件参数
 * @param {number} param0.scrollTop 滚动条的位置
 */
function handleScroll({ scrollTop }: { scrollTop: number }) {
  const titleEl = groupTitleRefs.value.find((titleEl: HTMLInputElement) => {
    // 获取标题的位置信息
    const { offsetHeight, offsetTop } = titleEl;
    // 判断标题是否在可视范围内
    return scrollTop >= offsetTop && scrollTop < offsetTop + offsetHeight;
  });
  // 只需处理一次
  if (titleEl && activeGroup.value !== titleEl.textContent) {
    activeGroup.value = titleEl.textContent || '';
    // 同步左侧的滚动条位置
    scrollToGroupBtn(activeGroup.value);
  }
}

/** 处理分组选中 */
function handleGroupSelected(group: string) {
  activeGroup.value = group;
  const titleRef = groupTitleRefs.value.find(
    (item: HTMLInputElement) => item.textContent === group,
  );
  if (titleRef) {
    // 滚动分组标题
    linkScrollbar.value?.setScrollTop(titleRef.offsetTop);
  }
}

/** 自动滚动分组按钮，确保分组按钮保持在可视区域内 */
function scrollToGroupBtn(group: string) {
  const groupBtn = groupBtnRefs.value
    .map((btn: ButtonInstance) => btn.ref)
    .find((ref: HTMLButtonElement | undefined) => ref?.textContent === group);
  if (groupBtn) {
    groupScrollbar.value?.setScrollTop(groupBtn.offsetTop);
  }
}

/** 是否为相同的链接（不比较参数，只比较链接） */
function isSameLink(link1: string, link2: string) {
  return link2 ? link1?.split('?')[0] === link2.split('?')[0] : false;
}

/** 处理详情选择 */
function handleProductCategorySelected(id: number) {
  // 生成 activeAppLink
  const url = new URL(activeAppLink.value.path, 'http://127.0.0.1');
  url.searchParams.set('id', `${id}`);
  activeAppLink.value.path = `${url.pathname}${url.search}`;

  // 关闭对话框，并重置 id
  detailSelectModalApi.close();
  detailSelectDialog.value.id = undefined;
}
</script>
<template>
  <Modal title="选择链接" class="w-[65%]">
    <div class="flex h-[500px] gap-2">
      <div class="flex flex-col">
        <!-- 左侧分组列表 -->
        <ElScrollbar
          wrap-class="h-full"
          ref="groupScrollbar"
          view-class="flex flex-col"
          class="border-r border-gray-200 pr-2"
        >
          <ElButton
            v-for="(group, groupIndex) in APP_LINK_GROUP_LIST"
            :key="groupIndex"
            class="!ml-0 mb-1 mr-4 !justify-start"
            :class="[{ active: activeGroup === group.name }]"
            ref="groupBtnRefs"
            :text="activeGroup !== group.name"
            :type="activeGroup === group.name ? 'primary' : 'default'"
            @click="handleGroupSelected(group.name)"
          >
            {{ group.name }}
          </ElButton>
        </ElScrollbar>
      </div>
      <!-- 右侧链接列表 -->
      <ElScrollbar
        class="h-full flex-1 pl-2"
        @scroll="handleScroll"
        ref="linkScrollbar"
      >
        <div
          v-for="(group, groupIndex) in APP_LINK_GROUP_LIST"
          :key="groupIndex"
          class="mb-4 border-b border-gray-100 pb-4 last:mb-0 last:border-b-0"
        >
          <!-- 分组标题 -->
          <div class="mb-2 font-bold" ref="groupTitleRefs">
            {{ group.name }}
          </div>
          <!-- 链接列表 -->
          <ElTooltip
            v-for="(appLink, appLinkIndex) in group.links"
            :key="appLinkIndex"
            :content="appLink.path"
            placement="bottom"
            :show-after="300"
          >
            <ElButton
              class="mb-2 ml-0 mr-2"
              :type="
                isSameLink(appLink.path, activeAppLink.path)
                  ? 'primary'
                  : 'default'
              "
              @click="handleAppLinkSelected(appLink)"
            >
              {{ appLink.name }}
            </ElButton>
          </ElTooltip>
        </div>
      </ElScrollbar>
    </div>
  </Modal>

  <DetailSelectModal title="选择分类" class="w-[65%]">
    <ElForm class="min-h-[200px]">
      <ElFormItem
        label="选择分类"
        v-if="
          detailSelectDialog.type === APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST
        "
      >
        <ProductCategorySelect
          v-model="detailSelectDialog.id"
          :parent-id="0"
          @update:model-value="handleProductCategorySelected"
        />
      </ElFormItem>
    </ElForm>
  </DetailSelectModal>
</template>
